/**
 * @file preprocess.c
 * @brief 音频预处理模块实现
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "preprocess.h"
#include "score_engine.h"

// 在MSVC下定义M_PI（如果未定义）
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

// 获取默认预处理配置
PreprocessConfig get_default_preprocess_config(int sample_rate) {
    PreprocessConfig config;
    
    // 设置默认高通截止频率为20Hz
    config.low_cut_freq = 20;
    
    // 设置默认低通截止频率为最大频率的一半或16000Hz(取较小值)
    config.high_cut_freq = (sample_rate / 2 < 16000) ? sample_rate / 2 : 16000;
    
    // 默认使用汉明窗
    config.window_type = WINDOW_HAMMING;
    
    return config;
}

// 音频归一化处理
static int normalize_audio(float* audio, int length) {
    if (!audio || length <= 0) {
        return ERROR_AUDIO_FRAME_INVALID;
    }
    
    // 找到最大振幅
    float max_amp = 0.0f;
    for (int i = 0; i < length; i++) {
        float abs_val = fabsf(audio[i]);
        if (abs_val > max_amp) {
            max_amp = abs_val;
        }
    }
    
    // 如果最大振幅接近零，不作归一化处理
    if (max_amp < 1e-6f) {
        return ERROR_SUCCESS;
    }
    
    // 归一化处理
    float scale = 1.0f / max_amp;
    for (int i = 0; i < length; i++) {
        audio[i] *= scale;
    }
    
    return ERROR_SUCCESS;
}

// 应用窗函数
static int apply_window(float* audio, int length, int window_type) {
    if (!audio || length <= 0) {
        return ERROR_AUDIO_FRAME_INVALID;
    }
    
    // 根据窗类型生成窗系数
    float* window = (float*)malloc(length * sizeof(float));
    if (!window) {
        return ERROR_OUT_OF_MEMORY;
    }
    
    for (int i = 0; i < length; i++) {
        float x = (float)i / (length - 1);
        
        switch (window_type) {
            case WINDOW_RECT:
                window[i] = 1.0f;
                break;
                
            case WINDOW_HANNING:
                window[i] = 0.5f * (1.0f - cosf(2.0f * M_PI * x));
                break;
                
            case WINDOW_HAMMING:
                window[i] = 0.54f - 0.46f * cosf(2.0f * M_PI * x);
                break;
                
            case WINDOW_BLACKMAN:
                window[i] = 0.42f - 0.5f * cosf(2.0f * M_PI * x) + 0.08f * cosf(4.0f * M_PI * x);
                break;
                
            default:
                // 默认使用汉明窗
                window[i] = 0.54f - 0.46f * cosf(2.0f * M_PI * x);
                break;
        }
    }
    
    // 应用窗函数
    for (int i = 0; i < length; i++) {
        audio[i] *= window[i];
    }
    
    // 释放窗系数
    free(window);
    
    return ERROR_SUCCESS;
}

// 简单的带通滤波器实现(这里是简化版，实际应用中应使用更高效的滤波算法)
static int apply_bandpass_filter(float* audio, int length, int sample_rate, int low_cut_freq, int high_cut_freq) {
    if (!audio || length <= 0 || sample_rate <= 0) {
        return ERROR_AUDIO_FRAME_INVALID;
    }
    
    // 检查截止频率是否有效
    if (low_cut_freq < 0 || high_cut_freq <= low_cut_freq || high_cut_freq > sample_rate / 2) {
        return ERROR_CONFIG_INVALID;
    }
    
    // 这里简化实现，实际应用中应该使用FFT或IIR滤波
    // TODO: 实现高效的带通滤波算法
    
    return ERROR_SUCCESS;
}

// 音频预处理
int preprocess_audio(float* audio, int length, PreprocessConfig* config) {
    if (!audio || length <= 0) {
        return ERROR_AUDIO_FRAME_INVALID;
    }
    
    if (!config) {
        return ERROR_CONFIG_INVALID;
    }
    
    int ret;
    
    // 1. 归一化处理
    ret = normalize_audio(audio, length);
    if (ret != ERROR_SUCCESS) {
        return ret;
    }
    
    // 2. 带通滤波(实际应用中需要知道采样率，这里简化处理)
    // 此处的采样率值应从引擎上下文传入
    int assumed_sample_rate = 48000; // 假设采样率
    ret = apply_bandpass_filter(audio, length, assumed_sample_rate, 
                                config->low_cut_freq, config->high_cut_freq);
    if (ret != ERROR_SUCCESS) {
        return ret;
    }
    
    // 3. 窗函数处理
    //ret = apply_window(audio, length, config->window_type);
    //if (ret != ERROR_SUCCESS) {
    //    return ret;
   // }
    
    return ERROR_SUCCESS;
} 